package org.deltaset.samples.petclinic.domain;

import java.util.List;
import javax.annotation.ManagedBean;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.deltaset.meta.annotation.DsFirstResult;
import org.deltaset.meta.annotation.DsMaxResult;
import org.deltaset.samples.petclinic.reference.PetType;

/**
 *
 * @author dmakariev
 */
@ManagedBean
public class PetRepositoryAddon extends AbstractRepository {

    public long countPets() {
        return entityManager().createQuery("SELECT COUNT(o) FROM Pet o", Long.class).getSingleResult();
    }

    public List<Pet> findAllPets() {
        return entityManager().createQuery("SELECT o FROM Pet o", Pet.class).getResultList();
    }

    public Pet findPet(Long id) {
        if (id == null) {
            return null;
        }
        return entityManager().find(Pet.class, id);
    }

    public List<Pet> findPetEntries(@DsFirstResult int firstResult, @DsMaxResult int maxResults) {
        return entityManager().createQuery("SELECT o FROM Pet o", Pet.class).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
    }

////////////////////
    private TypedQuery<Pet> findPetsByNameAndWeight(String name, Float weight) {
        if (name == null || name.length() == 0) {
            throw new IllegalArgumentException("The name argument is required");
        }
        if (weight == null) {
            throw new IllegalArgumentException("The weight argument is required");
        }
        EntityManager em = entityManager();
        TypedQuery<Pet> q = em.createQuery("SELECT o FROM Pet AS o WHERE o.name = :name AND o.weight = :weight", Pet.class);
        q.setParameter("name", name);
        q.setParameter("weight", weight);
        return q;
    }

    private TypedQuery<Pet> findPetsByOwner(Owner owner) {
        if (owner == null) {
            throw new IllegalArgumentException("The owner argument is required");
        }
        EntityManager em = entityManager();
        TypedQuery<Pet> q = em.createQuery("SELECT o FROM Pet AS o WHERE o.owner = :owner", Pet.class);
        q.setParameter("owner", owner);
        return q;
    }

    private TypedQuery<Pet> findPetsBySendRemindersAndWeightLessThan(boolean sendReminders, Float weight) {
        if (weight == null) {
            throw new IllegalArgumentException("The weight argument is required");
        }
        EntityManager em = entityManager();
        TypedQuery<Pet> q = em.createQuery("SELECT o FROM Pet AS o WHERE o.sendReminders = :sendReminders AND o.weight < :weight", Pet.class);
        q.setParameter("sendReminders", sendReminders);
        q.setParameter("weight", weight);
        return q;
    }

    private TypedQuery<Pet> findPetsByTypeAndNameLike(PetType type, String name) {
        if (type == null) {
            throw new IllegalArgumentException("The type argument is required");
        }
        if (name == null || name.length() == 0) {
            throw new IllegalArgumentException("The name argument is required");
        }
        name = name.replace('*', '%');
        if (name.charAt(0) != '%') {
            name = "%" + name;
        }
        if (name.charAt(name.length() - 1) != '%') {
            name = name + "%";
        }
        EntityManager em = entityManager();
        TypedQuery<Pet> q = em.createQuery("SELECT o FROM Pet AS o WHERE o.type = :type AND LOWER(o.name) LIKE LOWER(:name)", Pet.class);
        q.setParameter("type", type);
        q.setParameter("name", name);
        return q;
    }
}
